package com.hskn.hss.module.tlequipmonitor.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hskn.hss.config.Config;
import com.hskn.hss.module.tlchannel.entity.TlChannel;
import com.hskn.hss.module.tlchannel.mapper.TlChannelMapper;
import com.hskn.hss.module.tlequip.entity.TlEquip;
import com.hskn.hss.module.tlequip.mapper.TlEquipMapper;
import com.hskn.hss.module.tlequipmonitor.service.TlEquipMonitorService;
import com.hskn.hss.utils.Md5Util;
import com.hskn.hss.utils.MyHttpUtils;
import com.hskn.hss.utils.StringUtils;
import com.hskn.hss.utils.redis.RedisUtil;
import com.hskn.hss.utils.redis.key.EquipMonitorKey;
import com.hskn.hss.utils.redis.key.EquipOnlineForVideoKey;
import com.hskn.hss.utils.redis.key.OilExceptionTodayKey;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hskn
 * @since 2021-05-11
 */
@Slf4j
@Service
public class TlEquipMonitorServiceImpl implements TlEquipMonitorService {

    @Resource
    private TlEquipMapper tlEquipMapper;
    @Resource
    TlChannelMapper tlChannelMapper;

    @Async
    @Override
    public void refresh() {
        List<Map> result = new ArrayList<>();

        //所有启用并绑定的设备
        Map<String, Object> param = new HashMap();
        param.put("bindstatus", "1");
        param.put("status", "1");
        List<TlEquip> tlEquipList = tlEquipMapper.getTlEquipList(param);

        //车载定位设备
        List<TlEquip> carLocationTlEquipList = tlEquipList.stream().filter(tlEquip -> tlEquip.getEquipTypeName().equals("车辆定位设备")).collect(Collectors.toList());
        //设施视频
        List<TlEquip> facilityTlEquipList = tlEquipList.stream().filter(tlEquip -> tlEquip.getEquipTypeName().equals("视频设备")).collect(Collectors.toList());
        //车载监控
        List<TlEquip> carVideoTlEquipList = tlEquipList.stream().filter(tlEquip -> tlEquip.getEquipTypeName().equals("车载监控")).collect(Collectors.toList());

        //油感和车载定位
        for (TlEquip tlEquip : carLocationTlEquipList) {
            String equipcode = RedisUtil.get(OilExceptionTodayKey.token, tlEquip.getEquipcode(), String.class);
            String oilStatus = "0";
            if (StringUtils.isEmpty(equipcode)) {
                oilStatus = "1";
            }
            result.add(generateResultMap(tlEquip.getEquipcode(), "", tlEquip.getEquipTypeName(), tlEquip.getBindobjname(), "0", "0", "0", oilStatus));
        }
        //设施视频心跳
        for (TlEquip tlEquip : facilityTlEquipList) {
            Integer onlineVideo = RedisUtil.get(EquipOnlineForVideoKey.token, tlEquip.getEquipcode(), Integer.class);
            String videoLiveStatus = "0";
            String videoPlaybackStatus = "0";
            String videoHeartBit = "0";
            if (null != onlineVideo) {
                videoHeartBit = "1";
            }
            //获取设备通道
            QueryWrapper<TlChannel> tlChannelQueryWrapper = new QueryWrapper<>();
            tlChannelQueryWrapper.lambda().eq(TlChannel::getEquipid, tlEquip.getId());
            List<TlChannel> tlChannelList = tlChannelMapper.selectList(tlChannelQueryWrapper);
            if (!CollectionUtils.isEmpty(tlChannelList)) {
                for (TlChannel tlChannel : tlChannelList) {
                    //是否可以直播
                    boolean liveFlag = liveOpen(tlEquip.getEquipcode(), tlChannel.getChannelid());
                    if (liveFlag) {
                        videoLiveStatus = "1";
                    }
                    //是否可以回放
                    Date now = new Date();
                    String tenSecondBeforeTime = DateUtil.formatDateTime(DateUtil.offsetSecond(now, -10));
                    String endTime = DateUtil.formatDateTime(now);
                    boolean playbackFlag = playbackOpen(tlEquip.getEquipcode(), tlChannel.getChannelid(), tenSecondBeforeTime, endTime);
                    if (playbackFlag) {
                        videoPlaybackStatus = "1";
                    }
                    result.add(generateResultMap(tlEquip.getEquipcode(), tlChannel.getChannelid(), tlEquip.getEquipTypeName(), tlEquip.getBindobjname(), videoLiveStatus, videoPlaybackStatus, videoHeartBit, "0"));
                    try {
                        //暂停2秒
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        //车载视频心跳
        for (TlEquip tlEquip : carVideoTlEquipList) {
            Integer onlineVideo = RedisUtil.get(EquipOnlineForVideoKey.token, tlEquip.getEquipcode(), Integer.class);
            String videoLiveStatus = "0";
            String videoPlaybackStatus = "0";
            String videoHeartBit = "0";
            if (null != onlineVideo) {
                videoLiveStatus = "1";
                videoPlaybackStatus = "1";
                videoHeartBit = "1";
            }
            result.add(generateResultMap(tlEquip.getEquipcode(), "", tlEquip.getEquipTypeName(), tlEquip.getBindobjname(), videoLiveStatus, videoPlaybackStatus, videoHeartBit, "0"));
        }
        if (!CollectionUtils.isEmpty(result)) {
            RedisUtil.set(EquipMonitorKey.token, "", result);
        }
        //车载视频直播
        //车载视频回放
    }

    /**
     * 封装map
     *
     * @param equipcode
     * @param equipTypeName
     * @param bindobjname
     * @param videoLiveStatus
     * @param videoPlaybackStatus
     * @param videoHeartBit
     * @param oilStatus
     * @return
     */
    public Map generateResultMap(String equipcode, String channel, String equipTypeName, String bindobjname, String videoLiveStatus,
                                 String videoPlaybackStatus, String videoHeartBit, String oilStatus) {
        Map map = new HashMap();
        map.put("equipcode", equipcode);
        map.put("channel", channel);
        map.put("equipTypeName", equipTypeName);
        map.put("bindobjname", bindobjname);
        map.put("videoLiveStatus", videoLiveStatus);
        map.put("videoPlaybackStatus", videoPlaybackStatus);
        map.put("videoHeartBit", videoHeartBit);
        map.put("oilStatus", oilStatus);
        return map;
    }

    /**
     * 设施视频直播监测
     *
     * @param deviceId
     * @param channel
     */
    public static boolean liveOpen(String deviceId, String channel) {
        String dmsAdminUrlOpen = Config.getDmsAdminUrl() + "/api/playNVR/open";
        String appId = Config.getAppId();
        String secret = Config.getSecret();
        long timestamp = DateUtil.current();
        String param = "appId=" + appId +
                "&channel=" + channel +
                "&deviceId=" + deviceId +
                "&timestamp=" + timestamp +
                "&secret=" + secret;
        String sign = Md5Util.md5(param);

        JSONObject queryParam = new JSONObject();
        queryParam.put("appId", appId);
        queryParam.put("channel", channel);
        queryParam.put("deviceId", deviceId);
        queryParam.put("timestamp", timestamp);
        queryParam.put("sign", sign);
        log.info("====liveOpen:" + queryParam.toJSONString());

        String openResult = MyHttpUtils.sendPostJson(dmsAdminUrlOpen, queryParam.toJSONString());
        JSONObject openJson = JSON.parseObject(openResult);

        boolean openFlag = true;
        if (null == openJson) {
            openFlag = false;
        }
        Integer code = openJson.getInteger("code");
        if (code != 200) {
            openFlag = false;
        }

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //关闭流
        String dmsAdminUrlClose = Config.getDmsAdminUrl() + "/api/playNVR/close";
        String closeResult = MyHttpUtils.sendPostJson(dmsAdminUrlClose, queryParam.toJSONString());
        JSONObject closeJson = JSON.parseObject(closeResult);
        if (null != closeJson) {
            log.info("==直播关闭流,返回结果：" + closeJson.toJSONString());
        }

        return openFlag;
    }

    /**
     * 设施视频回放监测
     *
     * @param deviceId
     * @param channel
     * @param startTime
     * @param endTime
     */
    public boolean playbackOpen(String deviceId, String channel, String startTime, String endTime) {
        String dmsAdminUrlOpen = Config.getDmsAdminUrl() + "/api/playNVR/playbackOpen";
        String appId = Config.getAppId();
        String secret = Config.getSecret();
        long timestamp = DateUtil.current();
        String paramOpen = "appId=" + appId +
                "&channel=" + channel +
                "&deviceId=" + deviceId +
                "&endTime=" + endTime +
                "&startTime=" + startTime +
                "&timestamp=" + timestamp +
                "&secret=" + secret;
        String sign = Md5Util.md5(paramOpen);

        JSONObject queryParamOpen = new JSONObject();
        queryParamOpen.put("appId", appId);
        queryParamOpen.put("channel", channel);
        queryParamOpen.put("deviceId", deviceId);
        queryParamOpen.put("startTime", startTime);
        queryParamOpen.put("endTime", endTime);
        queryParamOpen.put("timestamp", timestamp);
        queryParamOpen.put("sign", sign);
        String openResult = MyHttpUtils.sendPostJson(dmsAdminUrlOpen, queryParamOpen.toJSONString());
        JSONObject openJson = JSON.parseObject(openResult);

        boolean openFlag = true;
        if (null == openJson) {
            openFlag = false;
        }
        Integer code = openJson.getInteger("code");
        if (code != 200) {
            openFlag = false;
        }

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //关闭流
        String dmsAdminUrlClose = Config.getDmsAdminUrl() + "/api/playNVR/playbackClose";
        String paramClose = "appId=" + appId +
                "&channel=" + channel +
                "&deviceId=" + deviceId +
                "&timestamp=" + timestamp +
                "&secret=" + secret;
        String signClose = Md5Util.md5(paramClose);

        JSONObject queryParamClose = new JSONObject();
        queryParamClose.put("appId", appId);
        queryParamClose.put("channel", channel);
        queryParamClose.put("deviceId", deviceId);
        queryParamClose.put("timestamp", timestamp);
        queryParamClose.put("sign", signClose);
        String closeResult = MyHttpUtils.sendPostJson(dmsAdminUrlClose, queryParamClose.toJSONString());
        JSONObject closeJson = JSON.parseObject(closeResult);
        if (null != closeJson) {
            log.info("==回放关闭流,返回结果：" + closeJson.toJSONString());
        }

        return openFlag;
    }

}
